package ltd.lxclud.worddemo;

import cn.hutool.http.HttpUtil;
import com.aspose.words.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;

/**
 * Application
 *
 * @Author zhujinrun
 * @Since 2025/5/9 11:44
 */
public class Application {

    public static void main(String[] args) throws Exception {

        registerWord2412();

        // 输入和输出文件路径
        String inputFilePath = "input_document.docx";
        String outputFilePath = "output_document.docx";

        URI uri = Application.class.getClassLoader().getResource(inputFilePath).toURI();
        System.out.println(uri);

        // 加载文档
        LoadOptions loadOptions = new LoadOptions();
        loadOptions.setLoadFormat(LoadFormat.DOCX);
        Document doc = new Document(String.valueOf(uri), loadOptions);  // 替换为你的输入文件路径

//        // 创建 PDF 保存选项
//        PdfSaveOptions options = new PdfSaveOptions();
//        // 可以设置各种 PDF 选项，例如：
//        options.setCompliance(PdfCompliance.PDF_17); // 设置 PDF 版本兼容性
//        // 将文档保存为 PDF
//        doc.save(outputFilePath, options);  // 替换为你想要的输出文件路径


        // 占位符和富文本内容
        String placeholder = "{{description}}";
        String htmlContent = "<div><p>这是插入的富文本内容。</p><img src=\"http://devstatic.yxzxyg.com/30600257-d07e-498f-905b-55202e10222b\" alt =\"示例图片\" /><span color=\"red\">示例图片</span></div>";

        // 查找占位符并替换
        FindReplaceOptions options = new FindReplaceOptions();
        options.setReplacingCallback(new ReplaceWithHtmlContent(htmlContent));
        doc.getRange().replace(placeholder, "", options);

        // 保存文档
        SaveOptions saveOptions = new OoxmlSaveOptions();
        saveOptions.setSaveFormat(SaveFormat.DOCX);
        doc.save(outputFilePath, saveOptions);

        System.out.println("文档处理成功！");
    }

    /**
     * aspose-words:jdk17:24.12 版本
     */
    public static void registerWord2412() {
        try {
            Class<?> zzodClass = Class.forName("com.aspose.words.zzod");
            Constructor<?> constructors = zzodClass.getDeclaredConstructors()[0];
            constructors.setAccessible(true);
            Object instance = constructors.newInstance(null, null);
            Field zzWws = zzodClass.getDeclaredField("zzWws");
            zzWws.setAccessible(true);
            zzWws.set(instance, 1);
            Field zzVZC = zzodClass.getDeclaredField("zzVZC");
            zzVZC.setAccessible(true);
            zzVZC.set(instance, 1);

            Class<?> zz83Class = Class.forName("com.aspose.words.zz83");
            constructors.setAccessible(true);
            constructors.newInstance(null, null);

            Field zzZY4 = zz83Class.getDeclaredField("zzZY4");
            zzZY4.setAccessible(true);
            ArrayList<Object> zzwPValue = new ArrayList<>();
            zzwPValue.add(instance);
            zzZY4.set(null, zzwPValue);

            Class<?> zzXuRClass = Class.forName("com.aspose.words.zzXuR");
            Field zzWE8 = zzXuRClass.getDeclaredField("zzWE8");
            zzWE8.setAccessible(true);
            zzWE8.set(null, 128);
            Field zzZKj = zzXuRClass.getDeclaredField("zzZKj");
            zzZKj.setAccessible(true);
            zzZKj.set(null, false);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static class ReplaceWithHtmlContent implements IReplacingCallback {
        private final String htmlContent;

        public ReplaceWithHtmlContent(String htmlContent) {
            this.htmlContent = htmlContent;
        }

        @Override
        public int replacing(ReplacingArgs e) throws Exception {
            // 获取占位符的起始位置
            DocumentBuilder builder = new DocumentBuilder((com.aspose.words.Document) e.getMatchNode().getAncestor(NodeType.DOCUMENT));
            builder.moveTo(e.getMatchNode());

            // 解析 HTML 内容
            org.jsoup.nodes.Document jsoupDoc = Jsoup.parse(htmlContent);

            // 遍历 HTML 文档的节点
            NodeTraversor.traverse(new NodeVisitor() {
                public void head(org.jsoup.nodes.Node node, int depth) {
                    if (depth < 1) return;
                    System.out.println("第" + depth + "层 : " + node.toString());
                    if (node instanceof Element) {
                        if (node.nodeName().equals("img")) {
                            // 插入图片
                            writeImage(builder, node);
                        } else if (node.nodeName().equals("video")) {
                            // 跳过视频
                        } else if (node.firstChild() instanceof TextNode) {
                            TextNode childElement = (TextNode) node.firstChild();
                            // 插入段落文本
                            builder.write(childElement.text());
                        }
                    }
                }

                public void tail(org.jsoup.nodes.Node node, int depth) {
                    // Do nothing
                }
            }, jsoupDoc.body());

            return ReplaceAction.REPLACE;
        }

        private void writeImage(DocumentBuilder builder, org.jsoup.nodes.Node node) {
            String imageUrl = node.attr("src");
            if (!imageUrl.isEmpty()) {
                byte[] imageBytes;
                try {
                    if (imageUrl.startsWith("http")) {
                        // 从 URL 下载图片
                        imageBytes = HttpUtil.downloadBytes(imageUrl);
                    } else {
                        // 从本地路径加载图片
                        imageBytes = Files.readAllBytes(Paths.get(imageUrl));
                    }
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
                try {
                    builder.insertImage(imageBytes);
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    }
}
